﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Runtime.Serialization.Formatters.Soap;
using System.Runtime.Serialization.Formatters.Binary;
using System.ServiceModel;
using System.Windows;

namespace RecommendatioNetwork
{
    public class Model
    {
        #region Property
        public Configuration MyConfiguration { get; set; }
        public Repository MyRepository { get; set; }
        public ServiceHost MyServiceHost { get; set; }
        public Sender MySender { get; set; }
        #endregion

        #region Costruttore
        //costruttore del modello
        public Model()
        {
            //Verifico se sono presenti i file di configurazione e del contenuto dei dati
            //Se sono presenti carico quei dati, altrimenti creo dei nuovi file vuoti

            //CARICAMENTO CONFIGURAZIONE
            MyConfiguration= null;
            //verifica se il file esiste già
            if (File.Exists("config.xml"))
            {
                // Creo il formatter adeguato
                SoapFormatter formatter = new SoapFormatter();

                // Apro in lettura il file
                using (FileStream file = new FileStream("config.xml", FileMode.Open, FileAccess.Read))
                {
                    MyConfiguration = formatter.Deserialize(file) as Configuration;
                }
            }
            if (MyConfiguration == null)
                //se config=null o il file non esisteva o era vuoto. In entrambi i casi devo creare un nuovo oggetto Configuration a aprtire dal suo costruttore di default
                MyConfiguration = new Configuration();

            //CARICAMENTO DATI
            MyRepository = null;
            //verifica se il file esiste già
            if (File.Exists("repository.bin"))
            {
                // Creo il formatter adeguato
                BinaryFormatter formatter = new BinaryFormatter();

                // Apro in lettura il file
                using (FileStream file = new FileStream("repository.bin", FileMode.Open, FileAccess.Read))
                {
                    MyRepository= formatter.Deserialize(file) as Repository;
                    MyRepository.SetIpServer();
                }
            }
            if (MyRepository == null)
                //se config=null o il file non esisteva o era vuoto. In entrambi i casi devo creare un nuovo oggetto Repository
                MyRepository = new Repository(this);


        }
        #endregion

        #region Metodi
        /// <summary>
        /// Il metodo ripristina la configurazione ai valori di default.
        /// </summary>
        public void ResetConfiguration()
        {
            MyConfiguration = new Configuration();
        }
        /// <summary>
        /// Il metodo resetta tutti i dati configurazione ai valori di default.
        /// </summary>
        public void ResetRepository()
        {
            MyRepository = new Repository(this);
        }
        /// <summary>
        /// Il metodo si occupa di serializzare e salvare su file le istanze degli oggetti Repository e Configuration, i cui riferimenti sono contenuti nella classe statica Depot
        ///
        /// </summary>
        /// <returns></returns>
        public bool SaveModel()
        {
            // Creo il formatter adeguato
            SoapFormatter formatter = new SoapFormatter();
            // Apro in scrittura un nuovo file o lo sovrascrive
            using (FileStream file = new FileStream("config.xml", FileMode.Create, FileAccess.Write))
            {
                // Effettuo la serializzazione
                formatter.Serialize(file, MyConfiguration);
                Console.WriteLine("Configurazione salvata");
            }

            // Apro in scrittura un nuovo file o lo sovrascrive
            BinaryFormatter formatterBinary = new BinaryFormatter();
            using (FileStream file = new FileStream("repository.bin", FileMode.Create, FileAccess.Write))
            {
                // Effettuo la serializzazione
                formatterBinary.Serialize(file, MyRepository);
                Console.WriteLine("Repository salvato");
            }
            return true;
        }
        public bool InitializeCommunication()
        { 
            try
            {
                //binding che utilizza HTTP come trasporto per l'invio di messaggi SOAP 1.1. Permette di esporre endpoint conformi a WS-I BP 1.1
                BasicHttpBinding binding = new BasicHttpBinding(BasicHttpSecurityMode.None);
                //inizializzo una nuova istanza della classe ServiceHost con il servizio di tipo Listener
                MyServiceHost = new ServiceHost(typeof(Listener));
                //aggiungo al mio ServiceHost il contratto, il binding e l'URI su cui avviarlo
                MyServiceHost.AddServiceEndpoint(typeof(IContract), binding, MyRepository.MyUri);
                //faccio passare il mio ServiceHost dallo stato Created allo stato Opening
                MyServiceHost.Open();
                //sottoscrivo gli eventi listnerSearch e addResponse del Listner sui metodi ListenerSearch e AddResponse del Repository
                //la sottoscrizione viene  solo dopo l'attivazione del servicehost.
                Listener.listnerSearch += new EventHandler(MyRepository.ListenerSearch);
                Listener.addResponse += new EventHandler(MyRepository.AddResponse);
                //creo l'istanza di Sender
                MySender = new Sender(MyRepository);
            }
            catch (Exception ee)
            {
                Console.WriteLine("ERRORE INIZIALIZZAZIONE SERVER!!!"+ee.ToString());
                return false;
            }
            return true;
        }
        #endregion
    }
}
